#include "GY_GraphicsDialFinite.h"

GY_GraphicsDialFinite::GY_GraphicsDialFinite(const QString &guid, QGraphicsItem *parent)
    : QGraphicsPolygonItem(parent),GY_Object(guid,this)
{
    initializationPropertyInfo();
    ///旋转点坐标
    QPointF rotationCenter=m_PropertyInfoMap.value("Position").propertyValue.value<QPointF>();

    ///指针长度和宽度
    m_length=200;
    m_width=10;

    m_ratil=0.1;

    m_absoluteAngle=0;//绝对角度
    m_relativeAngle=m_PropertyInfoMap.value("StartAngle").propertyValue.value<double>();//相对角度

    setDatumCoord(rotationCenter);

    ///绘制指针
    drawDialFinite();
    setTransformOriginPoint(rotationCenter);///设置旋转点
    setRotation(-m_relativeAngle);///旋转至起始角
    setCenterPointF(rotationCenter);
}
/**
 * @brief GY_GraphicsDialFinite::GY_GraphicsDialFinite
 * @param guid
 * @param rotationPonit
 * @param startAngle
 * @param sweptAngle
 * @param startValue
 * @param endValue
 * @param value
 * @param parent
 */
GY_GraphicsDialFinite::GY_GraphicsDialFinite(const QString &guid, const QPointF &rotationPonit, const double startAngle, const double sweptAngle, const double startValue, const double endValue, const double value, QGraphicsItem *parent)
    : QGraphicsPolygonItem(parent),GY_Object(guid,this)
{
    initializationPropertyInfo();
    ///旋转点坐标
    m_PropertyInfoMap["Position"].propertyValue=rotationPonit;

    ///起始角度和旋转范围
    m_PropertyInfoMap["StartAngle"].propertyValue=startAngle;
    m_PropertyInfoMap["SweptAngle"].propertyValue=sweptAngle;

    ///起始值和结束值
    m_PropertyInfoMap["StartValue"].propertyValue=startValue;
    m_PropertyInfoMap["EndValue"].propertyValue=endValue;

    ///指针长度和宽度
    m_length=200;
    m_width=10;

    m_ratil=0.1;

    ///相对0度的角度
    m_relativeAngle=startAngle;
    ///绝对角度（相对于起始角度）
    m_absoluteAngle=0;

    setDatumCoord(rotationPonit);

    ///绘制指针
    drawDialFinite();
    setTransformOriginPoint(rotationPonit);///设置旋转点
    setRotation(-m_relativeAngle);///旋转至起始角
    setValue(value);
    setCenterPointF(rotationPonit);
}

bool GY_GraphicsDialFinite::setValue(const double value)
{
    double startValue=m_PropertyInfoMap.value("StartValue").propertyValue.value<double>();
    double endValue=m_PropertyInfoMap.value("EndValue").propertyValue.value<double>();
    if(startValue<=endValue)//起始角对应的值小于等于结束角对应的值（值递增）
    {
        if(value<startValue)//需要设置的值小于了最小值（起始值）为无效值
            return false;

        if(value>endValue)//需要设置值大于了最大值（结束值）为无效值
            return false;

        else//需要设置值在起始值至结束值范围内，将实际值设为需要设置的值
            m_PropertyInfoMap["Value"].propertyValue=value;
    }

    if(startValue>endValue)//起始角对应的值大于结束角对应的值（值递减）
    {
        if(value>startValue)//需要设置的值大于了最大值（起始值）为无效值
            return false;

        if(value<endValue)//需要设置值小于了最小值（结束值）为无效值
            return false;

        else//需要设置值在起始值至结束值范围内，将实际值设为需要设置的值
            m_PropertyInfoMap["Value"].propertyValue=value;
    }

    double uintValue;
    if(endValue-startValue==0)
    {
        m_absoluteAngle=0;
        m_relativeAngle=m_PropertyInfoMap.value("StartAngle").propertyValue.value<double>();
        setRotation(-m_relativeAngle);//旋转至起始角位置
        return false;
    }
    else
    {
        double sweptAngle=m_PropertyInfoMap.value("SweptAngle").propertyValue.value<double>();

        uintValue=(value-startValue)/(endValue-startValue);
        m_absoluteAngle=uintValue*sweptAngle;
        m_relativeAngle=m_PropertyInfoMap.value("StartAngle").propertyValue.value<double>()+m_absoluteAngle;

        setRotation(-m_relativeAngle);//旋转至对应位置
        return true;
    }
}

void GY_GraphicsDialFinite::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen = this->pen();
    pen.setWidthF(pen.widthF()/painter->matrix().m11());
    painter->setPen(pen);
    painter->drawPolygon(this->polygon());
}

bool GY_GraphicsDialFinite::updatPoint(const QString &name, const QVariant &value)
{
    if(!value.canConvert<QPointF>())
    {
        return false;
    }
    if(name.endsWith("Position"))///中心点坐标
    {
        ///旋转点坐标
        QPointF rotationCenter=value.value<QPointF>();

        setDatumCoord(rotationCenter);

        ///绘制指针
        drawDialFinite();
        setTransformOriginPoint(rotationCenter);///设置旋转点
        setRotation(-m_relativeAngle);

        m_PropertyInfoMap["Position"].propertyValue=rotationCenter;
        setCenterPointF(rotationCenter);
        return true;
    }
    return false;
}

bool GY_GraphicsDialFinite::updateStartAngle(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>())
    {
        return false;
    }
    if(name.endsWith("StartAngle"))///起始角度
    {
        double startAngle=value.value<double>();
        m_PropertyInfoMap["StartAngle"].propertyValue=startAngle;
        double value=m_PropertyInfoMap.value("Value").propertyValue.value<double>();
        setValue(value);
        return true;
    }
    return false;
}

bool GY_GraphicsDialFinite::updateSweptAngle(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>())
    {
        return false;
    }
    if(name.endsWith("SweptAngle"))///旋转范围
    {
        double sweptAngle=value.value<double>();
        m_PropertyInfoMap["SweptAngle"].propertyValue=sweptAngle;
        double value=m_PropertyInfoMap.value("Value").propertyValue.value<double>();
        setValue(value);
        return true;
    }
    return false;
}

bool GY_GraphicsDialFinite::updateStartValue(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>())
    {
        return false;
    }
    if(name.endsWith("StartValue"))///开始值
    {
        double startValue=value.value<double>();
        m_PropertyInfoMap["StartValue"].propertyValue=startValue;
        double value=m_PropertyInfoMap.value("Value").propertyValue.value<double>();
        setValue(value);
        return true;
    }
    return false;
}

bool GY_GraphicsDialFinite::updateEndValue(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>())
    {
        return false;
    }
    if(name.endsWith("EndValue"))///结束值
    {
        double endValue=value.value<double>();
        m_PropertyInfoMap["EndValue"].propertyValue=endValue;
        double value=m_PropertyInfoMap.value("Value").propertyValue.value<double>();
        setValue(value);
        return true;
    }
    return false;
}

bool GY_GraphicsDialFinite::updateValue(const QString &name, const QVariant &value)
{
    if(!value.canConvert<double>())
    {
        return false;
    }
    if(name.endsWith("Value"))///值
    {
        double c_value=value.value<double>();
        if(setValue(c_value))
            return true;
    }
    return false;
}

void GY_GraphicsDialFinite::drawDialFinite()
{
        QVector<QPointF> points;
        points.append(m_datumTopCoord);
        points.append(m_datumLeftCoord);
        points.append(m_datumTailCoord);
        points.append(m_datumRightCoord);
        QPolygonF polygon(points);
        setPolygon(polygon);
}

void GY_GraphicsDialFinite::setDatumCoord(QPointF coord)
{
    qreal xpos;
    qreal ypos;
    ///设置顶部坐标
    xpos=coord.x()+m_length*(1-m_ratil);
    m_datumTopCoord.setX(xpos);
    m_datumTopCoord.setY(coord.y());

    ///设置尾部坐标
    xpos=coord.x()-m_length*m_ratil;
    m_datumTailCoord.setX(xpos);
    m_datumTailCoord.setY(coord.y());

    ///设置腰部左点坐标
    ypos=coord.y()-m_width/2;
    m_datumLeftCoord.setX(coord.x());
    m_datumLeftCoord.setY(ypos);

    ///设置腰部右点坐标
    ypos=coord.y()+m_width/2;
    m_datumRightCoord.setX(coord.x());
    m_datumRightCoord.setY(ypos);
}

void GY_GraphicsDialFinite::initializationPropertyInfo()
{
    ///旋转中心点
    GY_PropertyInfo positionPropertyInfo;
    positionPropertyInfo.propertyName="Position";
    positionPropertyInfo.propertyValue=QPointF(0,0);
    positionPropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsDialFinite::updatPoint;
    m_PropertyInfoMap.insert("Position",positionPropertyInfo);

    ///起始角
    GY_PropertyInfo startAnglePropertyInfo;
    startAnglePropertyInfo.propertyName="StartAngle";
    startAnglePropertyInfo.propertyValue=150;
    startAnglePropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsDialFinite::updateStartAngle;
    m_PropertyInfoMap.insert("StartAngle",startAnglePropertyInfo);

    ///范围角
    GY_PropertyInfo sweptAnglePropertyInfo;
    sweptAnglePropertyInfo.propertyName="SweptAngle";
    sweptAnglePropertyInfo.propertyValue=-120;
    sweptAnglePropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsDialFinite::updateSweptAngle;
    m_PropertyInfoMap.insert("SweptAngle",sweptAnglePropertyInfo);

    ///开始值
    GY_PropertyInfo startValuePropertyInfo;
    startValuePropertyInfo.propertyName="StartValue";
    startValuePropertyInfo.propertyValue=0;
    startValuePropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsDialFinite::updateStartValue;
    m_PropertyInfoMap.insert("StartValue",startValuePropertyInfo);

    ///结束值
    GY_PropertyInfo endValuePropertyInfo;
    endValuePropertyInfo.propertyName="EndValue";
    endValuePropertyInfo.propertyValue=1;
    endValuePropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsDialFinite::updateEndValue;
    m_PropertyInfoMap.insert("EndValue",endValuePropertyInfo);

    ///当前值
    GY_PropertyInfo valuePropertyInfo;
    valuePropertyInfo.propertyName="Value";
    valuePropertyInfo.propertyValue=0;
    valuePropertyInfo.updatePropertyFun=(GY_PropertyInfo::UpdatePropertyFun)&GY_GraphicsDialFinite::updateValue;
    m_PropertyInfoMap.insert("Value",valuePropertyInfo);
}
